﻿using AutoMapper;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.Entity.Print;
using Coldairarrow.IBusiness;
using Coldairarrow.IBusiness.PS;
using Coldairarrow.Util;
using Coldairarrow.Util.ClassLibrary;
using Coldairarrow.Util.Helper;
using EFCore.Sharding;
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Coldairarrow.Business.PS
{
    /// <summary>
    /// 打印服务
    /// </summary>
    public partial class PrintServiceBusiness : BaseBusiness<PrintQueue>, IPrintServiceBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IMapper _mapper;
        readonly IOperatorDept _odept;
        readonly IServiceProvider _ServiceProvider;
        /// <summary>
        /// 打印服务
        /// </summary>
        /// <param name="db"></param>
        /// <param name="svcProvider"></param>
        /// <param name="operator"></param>
        /// <param name="mapper"></param>
        /// <param name="odept"></param>
        public PrintServiceBusiness(IDbAccessor db, IServiceProvider svcProvider, IOperator @operator, IMapper mapper, IOperatorDept @odept) : base(db)
        {
            _ServiceProvider = svcProvider;
            _operator = @operator;
            _mapper = @mapper;
            _odept = @odept;
        }

        /// <summary>
        /// 按批次返回打印队列
        /// </summary>
        /// <param name="printer"></param>
        /// <param name="_mongodbOptions"></param>
        /// <param name="_redisOptions"></param>
        /// <returns></returns>
        /// <exception cref="BusException"></exception>
        public async Task<List<PrintQueue>> GetBatchListAsync(string printer, MongoDBOptions _mongodbOptions, RedisOptions _redisOptions)
        {
            PrintQueue entity = new PrintQueue();
            //从MongoDB队列中查找跟自己有关的队列的批次
            MongoDBHelper mongo = new MongoDBHelper(_mongodbOptions);
            entity = await mongo.FindOneByStatusAsync<PrintQueue>("PrintQueue", printer);
            if (entity == null)
            {
                throw new BusException("当前没有打印任务");
            }
            //如果批次不为空
            if (!entity.BatchNumber.IsNullOrEmpty())
            {
                //redis中记录当前批次
                _redisOptions.DbChannel = (int)Redis_Type.redis9;
                RedisSetHelper redis = new RedisSetHelper(_redisOptions);
                //获取当前的批次号
                string bn = "";
                if (!redis.GetString(printer).IsNullOrEmpty())
                {
                    bn = redis.GetString(printer);
                }
                //如果批次号已备别的打印机获取则return
                if (bn.Equals(entity.BatchNumber))
                {
                    throw new BusException("当前没有打印任务");
                }
                //查询本批次下的所有数据
                FilterDefinition<PrintQueue> filter = Builders<PrintQueue>.Filter.Eq("BatchNumber", entity.BatchNumber);
                var list = await mongo.FindListAsync<PrintQueue>("PrintQueue", filter);

                if (list != null)
                {
                    //如果本批次总数不够则return
                    if (list.Count < entity.JobCount)
                    {
                        throw new BusException("当前没有打印任务");
                    }
                    redis.SetString(printer, entity.BatchNumber);
                    //删除队列
                    await mongo.DeleteManyAsync<PrintQueue>("PrintQueue", filter);
                    //插入历史队列
                    await mongo.InsertManyAsync<PrintQueue>("PrintHistory" + DateTime.Now.ToString("yyyyMM"), list);
                }
                else
                {
                    throw new BusException("当前没有打印任务");
                }
                return list;
            }
            else
            {
                throw new BusException("当前没有打印任务");
            }
        }
        /// <summary>
        /// 按条件分页返回历史打印队列
        /// </summary>
        /// <param name="_mongodbOptions"></param>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <param name="startDay">上限日</param>
        /// <param name="endDay">下限日</param>
        /// <param name="keyword">收货单号，物料名称，规格和批次</param>
        /// <param name="pageIndex">页数</param>
        /// <param name="pageSize">每页记录数</param>
        /// <returns></returns>
        public List<HistoryPrintQueueDTO> GetHistoryBatchList(MongoDBOptions _mongodbOptions, string year, string month, int startDay, int endDay, string keyword, int pageIndex, int pageSize)
        {
            //默认当日的数据
            if (year == "")
            {
                year = DateTime.Now.Year.ToString();
            }
            if (month == "")
            {
                month = DateTime.Now.Month < 10 ? "0" + DateTime.Now.Month.ToString() : month;
            }
            else
            {
                month = Convert.ToInt32(month) < 10 ? "0" + month : month;
            }
            if (endDay == 0)
            {
                endDay = DateTime.Now.Day;
            }
            MongoDBHelper mongo = new MongoDBHelper(_mongodbOptions);
            string collName = "PrintHistory" + year + month;
            var client = mongo.GetClient<PrintQueue>(collName);
            string strStartDay = startDay < 10 ? "0" + startDay.ToString() : startDay.ToString();
            string strEndDay = endDay < 10 ? "0" + endDay.ToString() : endDay.ToString();
            BsonDocument queryCondition = new BsonDocument
            {
                { "Date",new BsonDocument{{"$gte", year + "-" + month + "-" + strStartDay },{"$lte", year + "-" + month + "-" + strEndDay } }}
            };
            if (!string.IsNullOrEmpty(keyword))
            {
                var orLikeArray = new BsonArray{
                {
                    new BsonDocument
                    {
                        {"No",new BsonRegularExpression($"/{keyword}/") }
                    }
                },
                {
                    new BsonDocument
                    {
                        {"Code",new BsonRegularExpression($"/{keyword}/") }
                    }
                },
                {
                    new BsonDocument
                    {
                        {"Name",new BsonRegularExpression($"/{keyword}/") }
                    }
                },
                {
                    new BsonDocument
                    {
                        {"TypeName",new BsonRegularExpression($"/{keyword}/") }
                    }
                },
                {
                    new BsonDocument
                    {
                        {"BatchNumber",new BsonRegularExpression($"/{keyword}/") }
                    }
                }
            };

                //根据收货单号查询打印队列
                List<PB_JobBookingQrCode> jobBookingQrCodes = Db.GetIQueryable<PB_JobBookingQrCode>().Where(m => (!string.IsNullOrEmpty(m.RecId)) && m.RecId.Contains(keyword)).ToList();
                jobBookingQrCodes.ForEach(aData =>
                {
                    //物料码查询
                    orLikeArray.Add(
                    new BsonDocument
                    {
                        {"No",new BsonRegularExpression($"/{aData.Id}/") }
                    });
                });
                jobBookingQrCodes.ForEach(aData =>
                {
                    if (!string.IsNullOrEmpty(aData.PackId)&&!orLikeArray.Contains(new BsonDocument { { "No", new BsonDocument { { "$eq", aData.PackId } } } } ))
                    {
                        //包码查询
                        orLikeArray.Add(
                        new BsonDocument { { "No", new BsonDocument { { "$eq", aData.PackId } } } });
                    }
                });

                BsonDocument bsonOr = new BsonDocument
            {
                {
                    "$or",orLikeArray
                }
            };
                queryCondition.AddRange(bsonOr);
            }
            var list = client.Find(queryCondition).ToList();
            list = list.OrderByDescending(m => m.Date).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            List<HistoryPrintQueueDTO> res = new List<HistoryPrintQueueDTO>();
            list.ForEach(aData=>{
                HistoryPrintQueueDTO historyPrint = new HistoryPrintQueueDTO();
                historyPrint.Id = aData.Id;
                historyPrint.No = aData.No;
                historyPrint.Name = aData.Name;
                historyPrint.TypeName = aData.TypeName;
                historyPrint.Date = aData.Date;
                historyPrint.Dept = aData.Dept;
                historyPrint.QrCode = aData.QrCode;
                historyPrint.Type = aData.Type;
                historyPrint.Status = aData.Status;
                historyPrint.Printer = aData.Printer;
                historyPrint.IsProduct = aData.IsProduct;
                historyPrint.Code = aData.Code;
                historyPrint.BatchNumber = aData.BatchNumber;
                historyPrint.JobCount = aData.JobCount;

                if (aData.Type == "Statistics")
                {
                    PB_JobBookingQrCode pB_JobBookingQrCode = Db.GetIQueryable<PB_JobBookingQrCode>().Where(m => m.Id == aData.No.Substring(0, 19)).FirstOrDefault();
                    if (pB_JobBookingQrCode!=null)
                    {
                        historyPrint.ReceivingId = pB_JobBookingQrCode.RecId;
                    }
                }
                if (aData.Type == "Package")
                {
                    PB_JobBookingQrCode pB_JobBookingQrCode = Db.GetIQueryable<PB_JobBookingQrCode>().Where(m => m.PackId == aData.No).FirstOrDefault();
                    if (pB_JobBookingQrCode!=null)
                    {
                        historyPrint.ReceivingId = pB_JobBookingQrCode.RecId;
                    }               
                }
                res.Add(historyPrint);
            });
            return res;
        }
        /// <summary>
        /// 按条件分页返回历史打印队列总页数
        /// </summary>
        /// <param name="_mongodbOptions"></param>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <param name="startDay">上限日</param>
        /// <param name="endDay">下限日</param>
        /// <param name="keyword">收货单号，物料名称，规格和批次</param>
        /// <param name="pageSize">每页记录数</param>
        /// <returns>总页数</returns>
        public int GetTotalPageCount(MongoDBOptions _mongodbOptions, string year, string month, int startDay, int endDay, string keyword, int pageSize)
        {
            //默认当日的数据
            if (year == "")
            {
                year = DateTime.Now.Year.ToString();
            }
            if (month == "")
            {
                month = DateTime.Now.Month < 10 ? "0" + DateTime.Now.Month.ToString() : DateTime.Now.Month.ToString();
            }
            else
            {
                month = Convert.ToInt32(month) < 10 ? "0" + month : month;
            }
            if (endDay == 0)
            {
                endDay = DateTime.Now.Day;
            }
            string collName = "PrintHistory" + year + month;
            MongoDBHelper mongo = new MongoDBHelper(_mongodbOptions);
            var client = mongo.GetClient<PrintQueue>(collName);
            string strStartDay = startDay < 10 ? "0" + startDay.ToString() : startDay.ToString();
            string strEndDay = endDay < 10 ? "0" + endDay.ToString() : endDay.ToString();

            BsonDocument queryCondition = new BsonDocument
            {
                { "Date",new BsonDocument{{"$gte", year + "-" + month + "-" + strStartDay },{"$lte", year + "-" + month + "-" + strEndDay } }}
            };
            if (!string.IsNullOrEmpty(keyword))
            {
                var orLikeArray = new BsonArray {
                {
                    new BsonDocument
                    {
                        {"No",new BsonRegularExpression($"/{keyword}/") }
                    }
                },
                {
                    new BsonDocument
                    {
                        {"Code",new BsonRegularExpression($"/{keyword}/") }
                    }
                },
                {
                    new BsonDocument
                    {
                        {"Name",new BsonRegularExpression($"/{keyword}/") }
                    }
                },
                {
                    new BsonDocument
                    {
                        {"TypeName",new BsonRegularExpression($"/{keyword}/") }
                    }
                },
                {
                    new BsonDocument
                    {
                        {"BatchNumber",new BsonRegularExpression($"/{keyword}/") }
                    }
                }
            };
                //根据收货单号查询打印队列
                List<PB_JobBookingQrCode> jobBookingQrCodes = Db.GetIQueryable<PB_JobBookingQrCode>().Where(m => (!string.IsNullOrEmpty(m.RecId)) && m.RecId.Contains(keyword)).ToList();
                jobBookingQrCodes.ForEach(aData =>
                {
                    //物料码查询
                    orLikeArray.Add(
                    new BsonDocument
                    {
                        {"No",new BsonRegularExpression($"/{aData.Id}/") }
                    });
                });
                jobBookingQrCodes.ForEach(aData =>
                {
                    if (!string.IsNullOrEmpty(aData.PackId) && !orLikeArray.Contains(new BsonDocument { { "No", new BsonDocument { { "$eq", aData.PackId } } } }))
                    {
                        //包码查询
                        orLikeArray.Add(
                        new BsonDocument { { "No", new BsonDocument { { "$eq", aData.PackId } } } });
                    }
                });


                BsonDocument bsonOr = new BsonDocument
            {
                {
                    "$or",orLikeArray
                }
            };
                queryCondition.AddRange(bsonOr);
            }
            var list = client.Find(queryCondition).ToList();
            if (list == null || list.Count == 0)
            {
                return 0;
            }
            int count = (list.Count + pageSize - 1) / pageSize;
            return count;
        }
    }
}
